import React, { useEffect, useMemo, useRef, useState } from 'react';

import { renderStream, muteStream, voiceToVideo, videoToVoice, sendCustomeizeMessage, stopScreenShare, switchCameraWithStream } from '@/utils/lib';
import { launchFullScreen, fullscreenEnabled, cancelFullScreen, dataURItoBlob } from '@/utils';

import AudioMedia from '@/components/AudioMedia';

import VideoTool, { ToolPrpos } from './VideoTool';
import DescMask from '@/components/DescMask';
import { useDispatch, useSelector } from 'react-redux';
import { setMuteAgentStream, setUpdateAgentStream, setAgentLeave, setRenderedStream } from '@/store/reducers/stream';
import Message from '@/utils/message';
import Instructions from './Instructions';
import { ReceiveBroadcastMap, useBusiness } from '../Context/BusinessContext';
import CustomerCanvas from './CustomerCanvas';
import { IBusinessStatus, ignoreBusiness } from '../Context/BusinessContext';
import useSyncState from '../hooks/useSyncState';
import { useStream } from '../Context/StreamContext';
import { useScreenSync } from '../Context/ScreenSyncContext';
import { useMenuContext } from '../Context/MenuContext';
import AgentService from '@/modules/Agent';
import backgroundEffect from '@/utils/BackgroundEffect';

import { useTranslation } from 'react-i18next';
import ReconnectMessageBox from './ReconnectMessageBox';
import { clearNetworkStatusData } from '@/store/reducers/networkStatus';

import { IBusinessName, IOperationName } from '@/modules/interface';
import MediaStatus from '@/modules/media-status/MediaStatus';

import styled from '@emotion/styled';
import { updateMediaRenderStatus } from '../../modules/Api';
import { uploadFileWithBlob } from '@/api';

interface VideoItemProps {
	id: string | undefined;
	clientId: string;
	streamMode: string;
	label: string;
	robotAudio?: string;
	role: string;
	customerRole?: string;
	userName: string;
	isScreenSyncMode: boolean;

	hangup?: () => void;
}

const RenderErrorMessage = styled.span`
	display: inline-block;
	position: absolute;
	top: 50%;
	left: 50%;
	transform: translate(-50%, -50%);
	font-size: 16px;
	color: #fff;
`;

const InstructionsSpan = styled.span`
	color: #d7d7d7;
	font-family: simsun;
	display: inline-block;
	width: 1.5em;
	vertical-align: bottom;
	overflow: hidden;
	animation: dot 3s infinite step-start;
	@keyframes dot {
		0% {
			width: 0;
			margin-right: 1.5em;
		}
		33% {
			width: 0.5em;
			margin-right: 1em;
		}
		66% {
			width: 1em;
			margin-right: 0.5em;
		}
		100% {
			width: 1.5em;
			margin-right: 0;
		}
	}
`;

const NetWork = styled.div`
	position: absolute;
	color: #fff;
	z-index: 2;
	right: 0;
	bottom: 0;
`;

const defaultTools = [
	{
		id: 1,
		icon: 'icon-widget-shipinchuangkou-yuyinkai',
		text: '',
		isActive: false,
		activeIcon: 'icon-widget-shipinchuangkou-yuyinguan',
		mode: 'unmute'
	},
	{
		id: 2,
		icon: 'icon-widget-shengyinkai',
		text: '',
		isActive: false,
		activeIcon: 'icon-widget-shengyinguan',
		mode: 'unmute'
	},
	{
		id: 3,
		icon: 'icon-widget-a-bianzu19',
		text: '',
		isActive: false,
		activeIcon: 'icon-widget-a-bianzu421',
		mode: 'update'
	},
	{
		id: 4,
		icon: 'icon-widget-quanping3',
		text: '',
		isActive: false,
		activeIcon: 'icon-widget-suoxiao',
		mode: 'scale'
	},
	{
		id: 5,
		icon: 'icon-widget-a-jietu2',
		text: '',
		isActive: false,
		activeIcon: 'icon-widget-a-jietu2',
		mode: 'screenshot'
	}
];

const VideoItem = (props: VideoItemProps) => {
	const { t } = useTranslation();
	const { id, clientId, streamMode, label, robotAudio, role, customerRole = '', userName, isScreenSyncMode = false, hangup } = props;
	const [streamName, setStreamName] = useState<string>('');
	const { session, customerMessage = { data: {} }, login, screenStreams, renderedStreams, agentStreams, setting, networkStatus } = useSelector((state: any) => state);
	const dispatch = useDispatch();
	const { BusinessTaskMap, setBusiness } = useBusiness();
	const [audioLevel, setAudioLevel] = useSyncState<number>(0);
	const [isMuteAudio, setIsMuteAudio] = useSyncState<boolean>(false);
	const streamModeRef = useRef(streamMode);
	const {
		getAudioLevel,
		suspendGetAudioLevel,
		resumeGetAudioLevel,
		streams,
		setStreams,
		audioStreams,
		videoInput,
		audioInput,
		audioOutput,
		setAudioInput,
		setAudioOutput,
		setVideoInput,
		largeStream
	} = useStream();
	const { screenSyncState } = useScreenSync();
	const { roomId, isJoinSession } = useMenuContext();
	const [removeBtn, setRemoveBtn] = useSyncState<boolean>(false);
	const [renderErrorMessage, setRenderErrorMessage] = useSyncState<boolean>(false);
	const [mediaStatus, setMediaStatus] = useState<{ status: string; notGood: boolean }>({ status: '', notGood: false });
	const [ccsStatus, setCcsStatus] = useState<{ status: string; id: string }>({ status: '', id: '' });

	const [tools, setTools] = useState<ToolPrpos[]>(defaultTools);

	const streamRef = useRef<any>(null);
	// 访客端渲染座席端的流的结果
	let customerRenderStreamResult = useRef<boolean>(false);
	let isCustomerRenderStreamResultSent = useRef<boolean>(false);

	useEffect(() => {
		if (AgentService.user?.userName !== userName || id?.includes('invite')) return;
		setAudioInput(AgentService.getAudioDeviceID() ? AgentService.getAudioDeviceID() : AgentService.getDefaultAudioInputDeviceID());
		setAudioOutput(AgentService.getSpeakerDeviceID() ? AgentService.getSpeakerDeviceID() : AgentService.getDefaultSpeaker());
		setVideoInput(AgentService.getVideoDeviceID());
		AgentService.addDeviceEventLinstener(async (target: { event: string; type: string; device: MediaDeviceInfo }) => {
			if (target.type === 'remove') {
				if (target.event === 'videoinput' && videoInput() === target.device.deviceId) {
					Message.warning(`视频源 ${target.device.label} 不可用，请检查！`);
					console.warn('device ');
				}
				if (target.event === 'audioinput' && audioInput() === target.device.deviceId) {
					Message.warning(`麦克风 ${target.device.label} 不可用，请检查！`);
				}
				if (target.event === 'audiooutput' && audioOutput() === target.device.deviceId) {
					Message.warning(`扬声器 ${target.device.label} 不可用，请检查！`);
				}
			}

			if (target.type === 'add') {
				if (target.event === 'videoinput' && target.device.deviceId === videoInput()) {
					try {
						await AgentService.updateStreamWithDeviceID(props.id!.toString(), target.device.deviceId);
						AgentService.setVideoInputDeviceId(target.device.deviceId);
					} catch (error) {
						console.log(error);
					}
				}
				if (target.event === 'audioinput' && target.device.deviceId === audioInput()) {
					try {
						await AgentService.updateStreamWithDeviceID(props.id!.toString(), target.device.deviceId);
						AgentService.setAudioInputDeviceId(target.device.deviceId);
					} catch (error) {
						console.log(error);
					}
				}
			}
		});

		MediaStatus.addPublishMediaStatusEventLinstener((data: any) => {
			if (!data) {
				return;
			}
			if (isLocalAgent()) {
				const items = data.filter((item: any) => item.streamLabel === label);
				if (items && items.length > 0) {
					setMediaStatus({ status: items[0].status, notGood: items[0].notGood });
				}
			}
		});

		MediaStatus.addRenderMediaStatusEventLinstener((data: any) => {
			if (!data) {
				return;
			}
			if (!isLocalAgent()) {
				const items = data.filter((item: any) => item.streamLabel === label);
				if (items && items.length > 0) {
					setMediaStatus({ status: items[0].status, notGood: items[0].notGood });
				}
			}
		});

		return () => {
			AgentService.removeDeviceEventListener();
			MediaStatus.removePublishMediaStatusEventLinstener();
			MediaStatus.removeRenderMediaStatusEventLinstener();
		};
	}, []);

	useEffect(() => {
		const { data = {} } = customerMessage;
		if (customerMessage.data && customerMessage.data.clientId) {
			switch (data.businessType) {
				case 'mute-stream':
					dispatch(setMuteAgentStream({ clientId: data.clientId, muteStatus: data.mode === 'mute' }));
					break;
				case 'upgrade-stream':
					dispatch(setUpdateAgentStream({ clientId: data.clientId, streamMode: data.mode }));
					break;
				default:
					break;
			}
		}
		if (data?.data?.clientId === AgentService.user?.clientId) {
			switch (data.businessType) {
				case 'notice-subscribe-result':
					customerRenderStreamResult.current = data?.data?.result;
					if (!data?.data?.result || streams().find((item: any) => item.id === largeStream()[0]?.id)) {
						updateMediaRenderStatus(AgentService.sessionId, data?.data?.result);
						isCustomerRenderStreamResultSent.current = true;
					}
					break;
				default:
					break;
			}
		}
	}, [customerMessage]);

	useEffect(() => {
		if (id?.includes('invite')) return;
		if (!id) return;
		getTools(tools);
		console.log('setTools:', streamMode, props);
		streamModeRef.current = streamMode;
	}, [streamMode]);

	useEffect(() => {
		if (id?.includes('invite')) return;
		if (!id) return;
		getTools(defaultTools);
		console.log('setTools:', streamMode, props);
	}, [userName]);

	useEffect(() => {
		if (id?.includes('invite')) return;
		const loginUserName = AgentService.user?.userName;
		let name = '';
		if (label.indexOf('screen') === -1) {
			if (loginUserName === userName) {
				setStreamName(t('mine') as string);
			} else {
				if (label.indexOf('agent') > -1) {
					name = t('agent') + `<${userName}>`;
				} else if (label.indexOf('customer') > -1) {
					name = t('client') + `<${userName}>`;
				} else {
					name = t('agent') + `<${userName}>`;
				}
				setStreamName(name!);
			}
		} else {
			name = t('agent') + `<${loginUserName}>` + t('desktop-share');
			setStreamName(name!);
		}
		if (label.indexOf('agent') > -1 && loginUserName !== userName && AgentService.agentStatus.isChief) {
			setRemoveBtn(true);
		} else if (loginUserName !== userName && AgentService.agentStatus.isChief && label.indexOf('agent') === -1 && label.indexOf('customer') === -1) {
			setRemoveBtn(true);
		} else {
			setRemoveBtn(false);
		}
	}, [label]);

	useEffect(() => {
		if (screenSyncState().status === 'end') {
			// const tool = tools.find(item => item.mode === 'update')!;
			// videoToolClick({ ...tool, isActive: true });
		}
	}, [screenSyncState().status]);

	useEffect(() => {
		console.log('reRender:', label, id, AgentService.getRenderedStreamById(label));
		if (id?.includes('invite')) return;

		if (!id) {
			return;
		}

		getTools(defaultTools);

		if (AgentService.getRenderedStreamById(label) && AgentService.getRenderedStreamById(label)?.stream) {
			console.log('getRenderedStreamById:', label, id);
			const stream = AgentService.getRenderedStreamById(label!)?.stream;
			let video = document.getElementById(id!) as HTMLVideoElement;
			video!.srcObject = stream as MediaProvider;
			video!.play();
			id && stream && getAudioLevel(id, vol => setAudioLevel(vol));
			return;
		}
		render(label, id!);
		if (userName === AgentService.user?.userName) {
			const video: HTMLVideoElement = document.getElementById(id!) as HTMLVideoElement;
			if (video && video.srcObject) {
				const stream = video.srcObject as MediaStream;
				setDefaultDevice(stream);
			}

			video.volume = 0;
		}

		setMediaStatus({ status: '', notGood: false });
		setCcsStatus({ status: '', id: '' });
	}, [id, label]);

	// setting
	useEffect(() => {
		console.log('startEffect:', videoInput(), audioInput(), AgentService.mediaDeviceController.getVideoInputDeviceID());
		startEffect();
	}, [AgentService.agentDao.getBackgroundId(), AgentService.agentDao.getWaterMarkId(), streamMode, videoInput(), audioInput()]);

	useEffect(() => {
		if (!largeStream()[0]) return;
		if (isCustomerRenderStreamResultSent.current) return;
		if (customerRenderStreamResult.current) {
			isCustomerRenderStreamResultSent.current = true;
			updateMediaRenderStatus(AgentService.sessionId, customerRenderStreamResult.current);
		}
	}, [largeStream()]);

	const startEffect = async () => {
		if (!isMe()) return;
		if (streamMode === 'audio') {
			backgroundEffect.stopEffect(true);
		}
		// 仅在video状态下启用虚拟背景
		if (streamMode !== 'video') {
			return;
		}
		// 虚拟背景

		const background = AgentService.agentDao.getBackgroundList().find(item => item.id === AgentService.agentDao.getBackgroundId());
		const watermark = AgentService.agentDao.getWaterMarkList().find(item => item.id === AgentService.agentDao.getWaterMarkId());
		if ((background && background.type !== 'no') || (watermark && watermark.type !== 'no')) {
			streamRef.current = await backgroundEffect.createEffectStream(label, id!, background!, watermark!, videoInput(), audioInput(), AgentService.configure.defaultMediaOptions);
		} else {
			streamRef.current = await backgroundEffect.createmediaStream(label, videoInput(), audioInput(), AgentService.configure.defaultMediaOptions);
		}

		console.log('startEffectVideo:', streamRef.current, videoInput(), audioInput());

		if (streamRef.current) {
			switchCameraWithStream(streamRef.current)
				.then(resp => {
					return new Promise((resolve, reject) => {
						try {
							const video: HTMLVideoElement = document.getElementById(id!) as HTMLVideoElement;
							video.srcObject = streamRef.current!.mediaStream;
							AgentService.setRenderedStream(label!, streamRef.current!.mediaStream);
							resolve(streamRef.current);
						} catch (error) {
							reject(error);
						}
					});
				})
				.catch(error => {
					console.warn(error);
				});
		}
	};

	const setDefaultDevice = async (stream: MediaStream) => {
		await AgentService.setInputDefaultDeviceIDWithSteam(stream);
		const videoTrack = stream.getVideoTracks();
		const audioTrack = stream.getAudioTracks();
		for (let track of videoTrack) {
			if (track.canvas) {
				// 是语音流，携带的小video是canvas
				setVideoInput(undefined);
			} else {
				if (track.getSettings().deviceId) {
					setVideoInput(track.getSettings().deviceId);
				}
			}
		}

		console.log('setVideoInput:', videoInput(), videoTrack[0].getSettings(), videoTrack[0], audioTrack[0], audioTrack[0].getSettings());
	};

	const render = async (label: string, videoId: string) => {
		try {
			if (!document.getElementById(videoId)) return;
			if (AgentService.getRenderedLabel(label)) return;

			AgentService.setRenderedLabel(label, { label, id: videoId });
			console.log('getRenderedLabel', AgentService.getRenderedLabel(label), id);
			const data = (await renderStream(
				label,
				videoId,
				(data: any) => {
					endScreenShare(data);
				},
				(stream: any) => {
					let video = document.getElementById(id!) as HTMLVideoElement;
					if (video) {
						video.srcObject = stream.mediaStream ? stream.mediaStream : stream;
						AgentService.setRenderedStream(label, video.srcObject as MediaStream);
					}
					console.log('render success MediaStream:', stream, video?.srcObject);
				}
			)) as any;
			if (data.status === 'error') {
				console.error('renderStream error:', data);
				setRenderErrorMessage(true);
			}

			// let video = document.getElementById(id!) as HTMLVideoElement;
			// let stream = video!.srcObject as MediaStream;
			// AgentService.setRenderedStream(label, stream);
			// console.log('render success renderStreamXXXXXX:', label, videoId, AgentService.getRenderedStreamById(label));

			// 虚拟背景
			if (setting.background.type !== 'none' || setting.watermark.type !== 'none') {
				await startEffect();
			}
			setTimeout(() => {
				id && getAudioLevel(id, vol => setAudioLevel(vol));
			}, 200);
		} catch (error) {
			console.log(error, 'render agent error');
		}
	};

	// 结束屏幕共享
	const endScreenShare = async (data: any) => {
		agentStreams.forEach(async (item: any) => {
			if (item.id === data) {
				dispatch(setAgentLeave(item.label));
				if (item.label.indexOf('screen') > -1) {
					Message.normal(t('screen-sharing-ended'));
					try {
						const resp = await stopScreenShare(screenStreams.screenPublicationId);
						const container = document.getElementById('widget-screen-share-parent-contianer');
						container && document.body.removeChild(container);
						console.log('stop screen share success', resp);
					} catch (error) {
						console.log('stop screen share error', error);
					}
				}
			}
		});
	};

	useEffect(() => {
		if (id?.includes('invite')) return;
		onScreenChange();
		return () => {
			setRenderErrorMessage(false);
		};
	}, []);

	useEffect(() => {
		console.log('acceptCallMode:', AgentService.acceptCallMode);
		if (AgentService.acceptCallMode.microphoneStatus === 'mute' && AgentService.user?.userName === userName) {
			muteStream('mute', 'audio', id!)
				.then(resp => {
					console.log('microphoneStatus mute:', resp);
					setIsMuteAudio(true);
					const list = [...tools];
					list[0].mode = 'mute';
					list[0].isActive = true;
					setTools([...list]);
				})
				.catch(e => {
					console.log('microphoneStatus mute:', e);
				});
		}
	}, [AgentService.acceptCallMode.microphoneStatus]);

	const checkIsFullScreen = () => {
		const isFullScreen = document.fullscreen || document.mozFullScreen || document.webkitIsFullScreen;
		return isFullScreen == undefined ? false : isFullScreen;
	};

	const onFullscreenchange = () => {
		if (checkIsFullScreen()) {
			let list = [...tools];
			list.forEach((item: ToolPrpos) => {
				if (item.mode === 'scale') {
					item.isActive = true;
				}
			});
			list = list.filter(item => item.mode === 'scale');
			if (removeBtn() && AgentService.agentStatus.isChief && AgentService.user?.userName !== userName) {
				setRemoveBtn(false);
			}
			setTools([...list]);
		} else {
			let list = [...tools];
			list.forEach((item: ToolPrpos) => {
				if (item.mode === 'scale') {
					item.isActive = false;
				}
			});
			console.log('exit fullscreen', label, clientId, role, streamMode, streamModeRef.current, AgentService.user?.clientId, list);
			if (label.indexOf('screen') > -1) {
				list = list.filter(item => item.mode === 'scale');
			} else if (AgentService.user?.clientId !== clientId) {
				// list = list.filter(item => item.mode !== 'update');
				if (role === 'agent' || streamModeRef.current === 'audio') {
					list = list.filter(item => item.id !== 1 && item.id !== 5 && item.id !== 3); // 其他坐席不需要截图功能，静音,降级为语音功能； 其他访客语音模式不需要截图，静音功能，降级为语音功能
				} else {
					list = list.filter(item => item.id !== 1);
				}
			} else {
				list = list.filter(item => item.id !== 2 && item.id !== 5); // 自己的画面。不需要截图
			}
			if (!removeBtn() && AgentService.agentStatus.isChief && AgentService.user?.userName !== userName) {
				setRemoveBtn(true);
			}
			setTools([...list]);
		}
	};

	// 监听全屏或退出全屏
	const onScreenChange = () => {
		document.getElementById(`video-box-${id}`)!.addEventListener('fullscreenchange', function (event: any) {
			// 非当前视频全屏不处理
			if (!event.target.id.includes(id)) return;
			onFullscreenchange();
		});

		/* Firefox */
		document.getElementById(`video-box-${id}`)!.addEventListener('mozfullscreenchange', function (event: any) {
			// 非当前视频全屏不处理
			if (!event.target.id.includes(id)) return;
			onFullscreenchange();
		});

		/* Chrome, Safari 和 Opera */
		document.getElementById(`video-box-${id}`)!.addEventListener('webkitfullscreenchange', function (event: any) {
			// 非当前视频全屏不处理
			if (!event.target.id.includes(id)) return;
			onFullscreenchange();
		});

		/* IE / Edge */
		document.getElementById(`video-box-${id}`)!.addEventListener('msfullscreenchange', function (event: any) {
			// 非当前视频全屏不处理
			if (!event.target.id.includes(id)) return;
			onFullscreenchange();
		});
		document.getElementById(`video-box-${id}`)!.addEventListener('webkitbeginfullscreen', (event: any) => {
			// 非当前视频全屏不处理
			if (!event.target.id.includes(id)) return;
			const list = [...tools];
			setTools(
				list.map(item => {
					if (item.mode === 'scale') {
						return { ...item, isActive: true };
					}
					return item;
				})
			);
		});
		document.getElementById(`video-box-${id}`)!.addEventListener('webkitendfullscreen', (event: any) => {
			// 非当前视频全屏不处理
			if (!event.target.id.includes(id)) return;
			const list = [...tools];
			setTools(
				list.map(item => {
					if (item.mode === 'scale') {
						return { ...item, isActive: false };
					}
					return item;
				})
			);
		});
	};

	const setMute = async (data: ToolPrpos) => {
		const source = data.mode === 'play' ? 'video' : 'audio';
		const mode = data.isActive ? 'unmute' : 'mute';
		console.log('mute:', mode, source, streamMode, id);
		let resp;
		try {
			if (clientId === AgentService.clientID) {
				const list = [...tools];

				resp = await muteStream(mode, source, id!);
				if (source === 'audio') {
					// mode === 'mute' ? suspendGetAudioLevel(id!) : resumeGetAudioLevel(id!);
					setIsMuteAudio(mode === 'mute');
					await (id && suspendGetAudioLevel(id));
				}
				if (mode === 'unmute') {
					await (id && getAudioLevel(id, vol => setAudioLevel(vol)));
				}
				setTools(
					list.map(item => {
						if (item.id === 1) {
							return { ...item, isActive: mode === 'mute' };
						}
						return item;
					})
				);
			} else {
				const audioModeStream = audioStreams().find((item: any) => item.clientId === clientId);
				if (audioModeStream) {
					const video: HTMLVideoElement = document.getElementById(audioModeStream.id!) as HTMLVideoElement;
					video.volume = data.isActive ? 1 : 0;
				} else {
					const video: HTMLVideoElement = document.getElementById(id!) as HTMLVideoElement;
					video.volume = data.isActive ? 1 : 0;
				}
				const list = [...tools];

				setTools(
					list.map(item => {
						if (item.id === 2) {
							return { ...item, isActive: mode === 'mute' };
						}
						return item;
					})
				);
			}
			console.log('setMute:', resp);
			let name = '';
			if (label.indexOf('agent') > -1) {
				name = t('agent') + `<${userName}>`;
			} else {
				name = t('client') + `<${userName}>`;
			}
			if (mode === 'mute') {
				// Message.normal(`${name}音量已关闭`);
			} else {
				// Message.normal(`${name}音量已开启`);
			}
		} catch (error) {
			console.log(error);
		}
	};

	const setScreenScale = (data: ToolPrpos) => {
		let ele = document.getElementById(`video-box-${id}`);
		if (fullscreenEnabled() && ele) {
			if (data.isActive) {
				cancelFullScreen();
			} else {
				launchFullScreen(ele);
			}
		}
	};

	/**
	 * 截图
	 * @param data
	 */
	const takeScreenShot = (data: ToolPrpos) => {
		console.log('takeScreenShot:', data, id, clientId, streamMode, label, robotAudio, role, userName);
		let taskKey = `${clientId}_${IBusinessName.SCREEN_SHOT}_${Math.floor(Math.random() * (999999999999 - 9 + 1)) + 9}`;
		BusinessTaskMap.addTask(taskKey, {
			name: IBusinessName.SCREEN_SHOT,
			clientId: clientId,
			status: IBusinessStatus.IN_PROGRESS,
			username: userName,
			userRole: AgentService.getSessionClientWithLabel(largeStream()[0].label)?.customerRole || '',
			cmdId: null
		});
		try {
			const stream = AgentService.getRenderedStreamById(label!)?.stream;
			const video = document.getElementById(id!) as HTMLVideoElement;
			// const video = document.getElementById(largeStream()[0].id!) as HTMLVideoElement;
			// const stream = AgentService.getRenderedStreamById(largeStream()[0].label)?.stream as MediaProvider;
			let canvas = document.createElement('canvas');
			let track = stream.getVideoTracks()[0];
			const { height, width } = track.getSettings();
			canvas.height = height;
			canvas.width = width;
			canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);
			let result = canvas.toDataURL('image/png');
			let fileName = Date.now() + 'screenshot' + '.png';
			let blob = dataURItoBlob(result);
			uploadFileWithBlob(blob, fileName)
				.then(async resp => {
					console.log('upload file', resp, resp.data.data);
					const { filename, size, url } = resp.data?.data;
					let responseData = {
						cmd: 'get-screenshot',
						data: {
							name: filename,
							size: size,
							url: url + `?token=${AgentService.getToken()}`
						},
						id: '',
						status: 'done'
					};
					let task = BusinessTaskMap.getTask(taskKey);
					setBusiness([
						{
							name: IBusinessName.SCREEN_SHOT,
							clientId: clientId,
							status: IBusinessStatus.DONE,
							username: userName,
							userRole: AgentService.getSessionClientWithLabel(largeStream()[0].label)?.customerRole || '',
							cmdId: null
						}
					]);
					BusinessTaskMap.addCompletedTask({ task: IBusinessName.SCREEN_SHOT, data: task!, response: responseData, isRead: false });
					BusinessTaskMap.delTask(taskKey); // 删除当前任务，防止邀请三方坐席，通知给其他坐席
					let messageData = {
						businessType: `save-screenshot`,
						url: resp.data?.data?.url
					};
					sendCustomeizeMessage(messageData, 'all');
				})
				.catch(error => {
					console.log(error, 'uploadFileWithBlob error');
					BusinessTaskMap.updateTaskStatus(clientId, IBusinessStatus.FAILED, null);
				});
		} catch (error) {
			let task = BusinessTaskMap.getTask(taskKey);
			setBusiness([
				{
					name: IBusinessName.SCREEN_SHOT,
					clientId: clientId,
					status: IBusinessStatus.FAILED,
					username: userName,
					userRole: AgentService.getSessionClientWithLabel(largeStream()[0].label)?.customerRole || '',
					cmdId: null
				}
			]);
			let responseData = {
				cmd: 'get-screenshot',
				data: {
					name: 'screenshot.png',
					size: 0,
					url: null
				},
				id: '',
				status: 'done'
			};
			BusinessTaskMap.addCompletedTask({ task: IBusinessName.SCREEN_SHOT, data: task!, response: responseData, isRead: false });
			BusinessTaskMap.delTask(taskKey); // 删除当前任务，防止邀请三方坐席，通知给其他坐席
		}
	};
	const setUpdate = async (data: ToolPrpos) => {
		const mode = data.isActive ? 'video' : 'audio';
		try {
			let resp;
			const source = data.isActive ? 'upgrade-video' : 'upgrade-audio';
			let messageData = {
				businessType: `upgrade-stream`,
				mode,
				source,
				clientId
			};
			if (clientId === AgentService.clientID) {
				console.log(data.isActive, 'setUpdate');
				resp = data.isActive ? await voiceToVideo(undefined, id, videoInput()) : ((await videoToVoice(audioInput())) as any);
				// AgentService.setRenderedStream(id!, stream.mediaStream);
				await sendCustomeizeMessage(messageData, 'all');
				if (!id || !resp) return;
				const video: HTMLVideoElement = document.getElementById(id!) as HTMLVideoElement;
				video.srcObject = resp.mediaStream;
				AgentService.setRenderedStream(label!, resp.mediaStream);
				await (id && getAudioLevel(id, vol => setAudioLevel(vol)));
				console.log('setUpdateMediaStream:', resp);
				if (AgentService.configure.preferenceSettings.isNotifyCustomerMediaUpgrade) {
					const customerId = largeStream()[0]?.clientId || '';
					let messageData2 = {
						businessType: `request_media_upgrade`,
						mode,
						role: 'customer',
						userName: largeStream()[0]?.userName || 'customer', // 访客名字
						clientId: customerId // 访客ID
					};
					resp = await sendCustomeizeMessage(messageData2, customerId);
				}
			} else {
				const mode = data.isActive ? 'video' : 'audio';
				let messageData = {
					businessType: `request_media_upgrade`,
					mode,
					role,
					userName,
					clientId
				};
				const resp = await sendCustomeizeMessage(messageData, clientId);
				Message.normal(`${t('closed')}${role === 'agent' ? t('agent') : t('client')} <${userName}> ${t('video-picture')}`);

				console.log(props, data, resp);
			}
		} catch (error) {
			if (label.indexOf('agent') > -1) {
				if (mode === 'video') {
					Message.warning(t('agent') + `<${userName}>` + t('switch-video-call-failed'));
				} else {
					Message.warning(t('agent') + `<${userName}>` + t('switch-voice-call-failed'));
				}
			}
		}
	};

	const videoToolClick = (data: ToolPrpos) => {
		switch (data.mode) {
			case 'play':
				setMute(data);
				break;
			case 'unmute':
				setMute(data);
				break;
			case 'mute':
				setMute(data);
				break;
			case 'update':
				setUpdate(data);
				break;
			case 'scale':
				setScreenScale(data);
				break;
			case 'screenshot':
				takeScreenShot(data);
				break;
			default:
				break;
		}

		// const list = [...tools];
		// list.forEach((item: ToolPrpos) => {
		// 	if (item.id === data.id) {
		// 		item.isActive = !item.isActive;
		// 	}
		// });
		// setTools(list);
	};

	const showAudioMedia = () => {
		// const tool = tools.find(item => item.mode === 'update');
		return streamMode === 'audio';
	};

	const getBusiness = () => {
		let broadcastData = ReceiveBroadcastMap.get(clientId);
		let data = BusinessTaskMap.getTask(clientId) || broadcastData?.data.content;
		// console.log('getBusiness ', broadcastData, data, clientId);
		if (data && ignoreBusiness.indexOf(data?.name) <= -1) {
			return data;
		}
	};

	const removeAgent = () => {
		dropClient(clientId);
	};

	const dropClient = (clientId: string) => {
		ivcs.agent.dropClient(
			clientId,
			(resp: any) => {
				console.log('drop client result', resp);
			},
			(error: any) => {
				console.log(error, 'dropClient');
				Message.error(t('drop-client-failed'));
			}
		);
	};

	const isLocalAgent = () => {
		return AgentService.user?.userName === userName;
	};

	const onHangup = () => {
		backgroundEffect.stopEffect(true);
		AgentService.hangup({ code: 400, reason: 'ams reconnect failed' });
		setMediaStatus({ status: '', notGood: false });
		setCcsStatus({ status: '', id: '' });
		MediaStatus.clearMediagData();
		dispatch(clearNetworkStatusData());
	};

	const getInviteItem = () => {
		return id?.indexOf(IOperationName.INVITE) !== -1;
	};

	useEffect(() => {
		// 处理本地ccs网络状态
		if (isLocalAgent()) {
			setCcsStatus({ status: networkStatus.ccsStatus, id: clientId });
		}
	}, [networkStatus.ccsStatus]);

	useEffect(() => {
		// 处理远端ccs网络状态
		if (!isLocalAgent()) {
			const items = networkStatus.remoteStatus.filter((item: any) => item.id === clientId);
			if (items && items.length > 0) {
				setCcsStatus({ status: items[0].status, id: clientId });
			}
		}
	}, [networkStatus.remoteStatus]);

	const isMe = () => {
		return userName === AgentService.user?.userName;
	};

	useEffect(() => {
		// 处理远端ccs网络状态
		if (!isLocalAgent() && ccsStatus.id === clientId) {
			const user = label.indexOf('customer') >= 0 ? t('client') : t('agent');
			if (['reconnecting'].includes(ccsStatus.status)) {
				// 访客/坐席 <访客ID/坐席ID> 与服务端会话中断！
				Message.warning(user + `<${userName}>` + t('session-disconnected') + '！');
			} else if (['resume-connect', 'connected'].includes(ccsStatus.status)) {
				// 访客/坐席 <访客ID/坐席ID> 与服务端重新连接成功！
				Message.normal(user + `<${userName}>` + t('reconnected-success') + '！');
			}
		}
	}, [ccsStatus.status]);

	const NetWorkGood = (
		<NetWork>
			<img src={require('../../assets/img/netWork-good.png')} alt="" width={20} height={16} />
		</NetWork>
	);

	const NetWorkNotGood = (
		<NetWork>
			<img src={require('../../assets/img/newWork-notGod.png')} alt="" width={20} height={16} />
		</NetWork>
	);

	const NetWorkFailed = (
		<NetWork>
			<img src={require('../../assets/img/netWork-failed.png')} alt="" width={20} height={16} />
		</NetWork>
	);

	const getNetWork = () => {
		if (['connecting', 'failed', 'disconnected'].includes(mediaStatus.status)) {
			return NetWorkFailed;
		} else if (mediaStatus.notGood) {
			return NetWorkNotGood;
		} else {
			return NetWorkGood;
		}
	};

	const renderTool = useMemo(() => {
		return <VideoTool tools={tools} onclick={videoToolClick} removeBtn={removeBtn()} removeAgent={removeAgent} id={id} showDeviceSelect={isLocalAgent()}></VideoTool>;
	}, [tools]);

	const getTools = (tools: ToolPrpos[]) => {
		let list = [...tools];
		if (AgentService.user?.userName !== userName) {
			// list = list.filter(item => item.mode !== 'update');
			list = list.filter(item => item.id !== 1);
			if (label.indexOf('screen') > -1) {
				list = list.filter(item => item.mode !== 'unmute');
			}

			if (streamMode === 'audio' || role === 'agent') {
				list = list.filter(item => item.mode !== 'update' && item.mode !== 'screenshot');
			} else {
				list = defaultTools
					.map(item => {
						if (list.find(v => v.id === item.id)) {
							return list.find(v => v.id === item.id)!;
						}
						return item;
					})
					.filter(item => item.id !== 1);
			}
		} else {
			setRemoveBtn(false);
			list = list.filter(item => item.id !== 2 && item.id !== 5); // 自己的画面没有声音开/截图功能
			if (streamMode === 'audio') {
				list.forEach(item => {
					if (item.mode === 'update') {
						item.isActive = true;
					}
				});
			} else {
				list.forEach(item => {
					if (item.mode === 'update') {
						item.isActive = false;
					}
				});
			}
		}

		console.log('getTools:', tools, list);

		setTools(list);
	};

	return (
		<div id={`video-box-${id}`} className="video-box">
			{getBusiness()?.status === IBusinessStatus.IN_PROGRESS || getBusiness()?.status === IBusinessStatus.START || getBusiness()?.status === IBusinessStatus.ACCEPTED ? (
				<Instructions businessData={getBusiness()} />
			) : undefined}
			{getInviteItem() ? undefined : <DescMask desc={streamName}></DescMask>}
			{customerRole ? <span className="customer-role">{customerRole}</span> : undefined}
			<video className={'other-streams'} x5-video-player-type="h5" controlsList="nodownload nofullscreen" playsInline autoPlay id={id} muted={isMe() ? true : false}></video>
			{showAudioMedia() ? (
				<AudioMedia
					classname="audio"
					iconClassName={checkIsFullScreen() ? 'big-icon' : 'small-icon'}
					iconWidth={checkIsFullScreen() ? '64px' : '32px'}
					iconHeight={checkIsFullScreen() ? '64px' : '32px'}
					audioLevel={audioLevel()}
					isMuteAudio={isMuteAudio()}
				></AudioMedia>
			) : undefined}
			{renderTool}
			<CustomerCanvas id={id} />
			{renderErrorMessage() ? <RenderErrorMessage>{t('playback-stream-error')}</RenderErrorMessage> : undefined}
			{/* failed'|'connecting'|'connected'|'disconnected'|'quality-report */}
			{getNetWork()}
			{/* ccsStatus */}
			{isLocalAgent() && ['reconnecting', 'offline'].includes(ccsStatus.status) ? <ReconnectMessageBox onHangup={onHangup} type="ccs" /> : null}
			{!isLocalAgent() && ccsStatus.id === clientId && ['reconnecting'].includes(ccsStatus.status) ? (
				<div className="render-media-status">
					<span className="label">{t('session-broken')}，</span>
					<span className="label">
						{t('reconnnecting')}
						<InstructionsSpan>...</InstructionsSpan>
					</span>
				</div>
			) : null}
		</div>
	);
};

export default VideoItem;
